#include "ElicObject.h"
int ElicObject::modcop_list_name = 0;
int ElicObject::model_ant_name = 0;
int ElicObject::model_post_name = 0;
bool ElicObject::compiled = false;

ElicObject::ElicObject() 
{

}
ElicObject::~ElicObject()
{
  free(modcop);
  free(model_ant);
  free(model_post);
}

void ElicObject::Init()
{
 
 
 
  drotinc = 0.0;
  drot = 0.0;
  rot_ant = 0.0;
  rot_post = 0.0;
  modcop = NULL;
  model_ant = NULL;
  model_post = NULL;
  
  weakroket_count_tot = 0; 
  heavyroket_count_tot = 0;
  weakroket_count = 0; 
  heavyroket_count = 6;
  choose_sx_dx = true;
  roket_ready = true;
  bullet_ready  = true;
  shootWR = false;               //flag abilità sparo
  shootHR = false;
  shootB = false;
  
  LoadRoket();    
  LoadModel();
  if (!compiled) LoadLists();
}

void ElicObject::LoadRoket()
{
  //carico i missili
  for(int i= 0;i < ROKET_NUM ;i++)  
  {
      rokets[i] = new RoketObject(state);
      rokets[i]->Init();
  }
  
Reset_WeakRoket();
Reset_HeavyRoket();  
  
}

void ElicObject::Reset_HeavyRoket()
{
  rokets[6]->Init();
  rokets[7]->Init();
  rokets[6]->SetDisp(ROKET_XV_DISP,ROKET_YH_DISP,ROKET_Z_DISP);
  rokets[7]->SetDisp(-ROKET_XV_DISP,ROKET_YH_DISP,ROKET_Z_DISP);
  rokets[6]->SetType(HEAVY_ROKET);
  rokets[7]->SetType(HEAVY_ROKET);
   
}

void ElicObject::Reset_WeakRoket()
{
  //posiziono i missili nelle ali dell'elicottero
  rokets[0]->Init();
  rokets[1]->Init();
  rokets[2]->Init();
  rokets[3]->Init();
  rokets[4]->Init();
  rokets[5]->Init();
  
  rokets[0]->SetDisp(ROKET_XF_DISP,ROKET_YH_DISP,ROKET_Z_DISP);
  rokets[2]->SetDisp(ROKET_XV_DISP,ROKET_YL_DISP,ROKET_Z_DISP);
  rokets[4]->SetDisp(ROKET_XF_DISP,ROKET_YL_DISP,ROKET_Z_DISP);
  rokets[0]->SetType(WEAK_ROKET);
  rokets[2]->SetType(WEAK_ROKET);
  rokets[4]->SetType(WEAK_ROKET);
  
  rokets[1]->SetDisp(-ROKET_XF_DISP,ROKET_YH_DISP,ROKET_Z_DISP);
  rokets[5]->SetDisp(-ROKET_XV_DISP,  ROKET_YL_DISP,ROKET_Z_DISP);
  rokets[3]->SetDisp(-ROKET_XF_DISP,ROKET_YL_DISP,ROKET_Z_DISP);
  rokets[1]->SetType(WEAK_ROKET);
  rokets[3]->SetType(WEAK_ROKET);
  rokets[5]->SetType(WEAK_ROKET);
}

void ElicObject::LoadModel()
{
  //carico la scocca dell'elicottero
  modcop = glmReadOBJ(COP_SPM_RES);
  glmScale(modcop,SCALE_FACTOR);

  //carico l'alica principale
  model_ant = glmReadOBJ(COP_ELANT_MOD);
  glmScale(model_ant,SCALE_FACTOR);

  //carico l'elica posteriore  
  model_post = glmReadOBJ(COP_ELPOS_MOD);
  glmScale(model_post,SCALE_FACTOR);
  
  //carico i missili
  //glmLinearTexture(modelic);  

}

void ElicObject::LoadLists()
{
    modcop_list_name = glmList(modcop,GLM_SMOOTH|GLM_MATERIAL);    
    model_ant_name = glmList(model_ant,GLM_SMOOTH|GLM_MATERIAL);      
    model_post_name = glGenLists(1);
    glNewList(model_post_name,GL_COMPILE);
           glTranslatef(9,4,0.3);
           glColor3f(0.1,0.1,0.1);
           gluCylinder(state->quad_obj,0.15,0.15,1.1,5,5);
           glTranslatef(0,0,1);
    glEndList();   
    
    compiled = true; 
}

void ElicObject::Draw()
{
time_t tact;
time(&tact);

//calcolo possibilità di sparo
//if ( difftime(tact,bullet_time) > RELAY_BULLET) bullet_ready = true;
if ( difftime(tact,roket_time) > RELAY_ROKET)  roket_ready = true;

               
glPushMatrix();
glLoadIdentity();
           //elicottero
           glRotatef(pos.angY,0,1,0);  
           glRotatef(-90,0,1,0);               //ruoto il modello di 90 gradi
           glTranslatef(-23,3,25.1);     
           
           glCallList(modcop_list_name);
           
           glTranslatef(23,-3,-25.1);
           
          
           //elica anteriore
           glRotatef(rot_ant,0,1,0);          
           glTranslatef(-25,4.2,25);
           
           glCallList(model_ant_name);
           glEnable(GL_COLOR_MATERIAL);
           glTranslatef(25,-4.2,-25);
           glRotatef(-rot_ant,0,1,0);
           
                        
           //elica posteriore
           glCallList(model_post_name);
           glRotatef(rot_ant,0,0,1);
           glScalef(0.3,2.5,0.04);
           glutSolidCube(1.6);
                   
           
glPopMatrix();

//disegno i missili
for(int i = 0;i < ROKET_NUM;i++) 
       rokets[i]->Draw();

for(int i = 0;i < MAX_BULLET_NUM;i++) 
        if (bullets[i] != NULL) bullets[i]->Draw();
       
}

void ElicObject::DoIdle()
{
//ruoto le pale
rot_ant += drot; 

 // controllo se sono in sparo
if (shootWR) ShootWeakRoket();
if (shootHR) ShootHeavyRoket();
if (shootB) ShootBullet();
    

//abilito il movimento inerziale
if (state->rotating != 0) 
    if (pos.angY < MAX_ANG_INE && pos.angY > -MAX_ANG_INE)     pos.angY = pos.angY - state->rotating * 0.1;

if (state->rotating == 0)
    {
      if (pos.angY > 0.0) pos.angY = pos.angY - MAX_INC_ANG_INE;
      if (pos.angY < 0.0) pos.angY = pos.angY + MAX_INC_ANG_INE;
    }
       



// aggiorno la posizione dell'elicottero    
 pos.x = state->cam_posX;   
 pos.y = state->cam_posY;
 pos.z = state->cam_posZ;


//muovo i proiettili
for (int i = 0; i < bullet_count_tot; ++i)
        if (bullets[i] != NULL && bullets[i]->visible) bullets[i]->DoIdle(); 
        else { 
               delete bullets[i];
               bullets[i] = NULL;
              }

//muovo i missili
for (int i = 0; i < ROKET_NUM; ++i) 
{
    rokets[i]->SetPosDriection(pos.x,pos.y,pos.z,pos.angY);
    rokets[i]->DoIdle();
}    

  

}

void ElicObject::DoIdleTakeoff()
{
//ruoto le pale
rot_ant += drot; 
//controllo per il decollo
    
    if (drotinc < 0.05) drotinc  += 0.001;
    if (drot < MAX_VEL_ROT) drot += drotinc;
    else 
    {
        state->takeoff = true;
         time(&(state->time));  //tempo di inizio del gioco
    } 

}

//lancia un missile pesante
void ElicObject::ShootWeakRoket()
{
  if(weakroket_count_tot < MAX_WEAK_ROKET_NUM  && roket_ready)
  {  
    
    rokets[weakroket_count]->Shoot();
    time(&roket_time);                 //prndo il tempo dello sparo
    roket_ready = false;
  
    if(weakroket_count == 5)  weakroket_count = 0;
    else                      weakroket_count++;
    
   
    weakroket_count_tot++;
  } 
  
  if(weakroket_count_tot == MAX_WEAK_ROKET_NUM-5) rokets[0]->SetIvisible();
  if(weakroket_count_tot == MAX_WEAK_ROKET_NUM-4) rokets[1]->SetIvisible();
  if(weakroket_count_tot == MAX_WEAK_ROKET_NUM-3) rokets[2]->SetIvisible();
  if(weakroket_count_tot == MAX_WEAK_ROKET_NUM-2) rokets[3]->SetIvisible();
  if(weakroket_count_tot == MAX_WEAK_ROKET_NUM-1) rokets[4]->SetIvisible();
  if(weakroket_count_tot == MAX_WEAK_ROKET_NUM) rokets[5]->SetIvisible();
  
}

//lancia un missile pesante
void ElicObject::ShootHeavyRoket()
{
  if(heavyroket_count_tot < MAX_HEAVY_ROKET_NUM && roket_ready)
  {  
    rokets[heavyroket_count]->Shoot();
    time(&roket_time);                 //prndo il tempo dello sparo
    roket_ready = false;
    
    if(heavyroket_count == 7)  heavyroket_count = 6;
    else                       heavyroket_count++;
    
    
    heavyroket_count_tot++;
    
  } 
  
  if(heavyroket_count_tot == MAX_HEAVY_ROKET_NUM-1) rokets[6]->SetIvisible();
  if(heavyroket_count_tot == MAX_HEAVY_ROKET_NUM) rokets[7]->SetIvisible();
  
} 

//lancia un proiettile
void ElicObject::ShootBullet()
{
  if(bullet_count_tot < MAX_BULLET_NUM)//  && bullet_ready)
  { 
    BulletObject * b = new BulletObject(state);
    b->Init();
    
    
    //calcolo la posizione da dove far partirelo sparo
    float dx = 3.2 * cos(state->cam_angY* PI_DIV_180);
    float dz = 3.2 * sin(state->cam_angY* PI_DIV_180);
    
    
    if (choose_sx_dx)   b->SetPosDirection(-(pos.x + dx),-pos.y,-(pos.z + dz ),-pos.angY), choose_sx_dx = false;
    else                b->SetPosDirection(-(pos.x - dx),-pos.y,-(pos.z - dz),-pos.angY), choose_sx_dx = true;
    
    bool flag = false;
    for (int i = 0;(!flag && i <= bullet_count_tot);i++)
          if (bullets[i] == NULL) bullets[i] = b,flag = true;
  
    
    //time(&bullet_time);                 //prendo il tempo dello sparo
    bullet_ready = false;
    bullet_count_tot++;
  }
  

}

